<?php
namespace app\admin\controller;
vendor('wechat/autoload');
use EasyWeChat\Foundation\Application;
use think\Config;
use think\Controller;
use think\Url;

/**
 * 网页授权控制器，这个控制器里的所有方法都需要网页授权才能访问
 * Class MpOauth
 * @package app\admin\controller
 * 要获取目前绑定的微信公众号则使用get_bind_mp()
 */
abstract class MpOauth extends Controller {
    const SESSION_PREFIX = 'weipeter_';
    const SESSION_KEY_INFO = 'oauth_user_info';
    const SESSION_KEY_TARGET_URL = 'oauth_target_url';
    /**
     * 不使用网页授权
     */
    const SCOPES_NOT_OAUTH = 'not_oauth';
    /**
     * 不需要关注公众号
     */
    const SCOPES_SNSAPI_BASE = 'snsapi_base';
    /**
     * 需要关注公众号
     */
    const SCOPES_SNSAPI_USERINFO = 'snsapi_userinfo';
    /**
     * 开放平台网页登录时用到
     */
    const SCOPES_SNSAPI_LOGIN = 'snsapi_login';

    private $_callback;
    private $_app;

    protected function _initialize()
    {
        parent::_initialize();

        // 是否默认全部方法网页授权
        $this->_callback = Url::build('admin/MpAccess/oauthCallback');
        $scopes = $this->getScopes();
        $oauthOptions = [];
        $needAuth = !in_array(self::SCOPES_NOT_OAUTH,$scopes);

        if($needAuth){
            $oauthOptions = [
                'oauth'=>[
                    'scopes' =>$scopes,
                    'callback'=>$this->_callback,
                ]
            ];
        }

        // 初始化公众号Application
        $bindMp = get_bind_mp();

        $options = array_merge(
            Config::get('mp_options'),
            [
                'app_id'=> $bindMp['appid'],
                'secret'=> $bindMp['appsecret'],
                'token' => $bindMp['token'],
            ],
            $oauthOptions
        );

        $this->_app = new Application($options);

        if($needAuth&&!session(self::SESSION_KEY_INFO,'',self::SESSION_PREFIX)) {
            // 未授权
            session(self::SESSION_KEY_TARGET_URL,
                $this->getCurUrl(),
                self::SESSION_PREFIX);
            $this->_app->oauth->redirect()->send();
        }

    }

    protected function getApp() {
        return $this->_app;
    }



    /**
     * 全局授权
     * 返回数组，返回需要的Scopes，如果这里返回的不是SCOPES_NOT_OAUTH，则所有方法都会被网页授权，如果返回SCOPES_NOT_OAUTH，则所有网页都不会被网页授权
     * @return mixed
     */
    abstract protected function getScopes();


    /**
     * 获取授权信息
     * @param array $scopes
     * @return mixed
     * 如果已授权，则获取信息，参数$scopes没用
     * 如果未授权，则使用$scopes指定的区域来授权
     */
    public function getInfo($scopes = [self::SCOPES_SNSAPI_USERINFO]) {
        if($info = session(self::SESSION_KEY_INFO,'',self::SESSION_PREFIX)) {
            // 已授权
            return $info;
        }else {
            // 未授权
            $this->_app['config']->set('oauth.callback',$this->_callback);
            $this->_app['config']->set('oauth.scopes',$scopes);
            session(self::SESSION_KEY_TARGET_URL,
                $this->getCurUrl(),
                self::SESSION_PREFIX);
            $this->_app->oauth->redirect()->send();
        }

    }
    private function getCurUrl() {
        return 'http://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
    }
}